#!/usr/bin/python


import csv,pickle

f = open("mcpots.pkl")
reveffects = pickle.load(f)
f.close()
revpots = {}

alleffects = {}
for effects,values in reveffects.items():
	alleffects[values[0]] = effects
	for value in values:
		revpots[value] = values[0]
	
from collections import defaultdict

nodes = defaultdict(dict)
f  = open("pottrans")
for line in f:
	src,ingr,dst = line.split("|")
	try:
		nodes[int(src)][ingr]=int(dst)
	except KeyError:
		print("couldn't find entry for"+src)
f.close()


class Ing():
	def __init__(self):
		self.best = defaultdict(lambda : 100)
		self.lists = {}
		self.values = {}
	def add(self,list,value):
		fs = frozenset(list)
		l = len(list)
		if self.best[fs] > l:
			self.best[fs] = l
			self.lists[fs] = list
			self.values[fs] = value
dedup = defaultdict(Ing)
ings = (
"Water"				,
"Sugar"				,
"GhastTear"			,
"SpiderEye"			,
"FermentedSpiderEye",
"BlazePower"		,
"MagmaCream"		,
"NetherWart"		,
		)
import itertools

for combcount in range(len(ings)+1):
	for excludes in itertools.combinations(ings,combcount):
		filename = "dij-"+"".join(excludes)
		print("Working on "+filename)
		#now, nodes is a graph, where each node is a potion_value, and each edge is the application of one ingredient
		try:
			f = open(filename)
			P = pickle.load(f)
		except:
			P = {} # Predecessor dict
			pass
		finally:
			f.close()

		start = 0
		if not P: #skip this if we've already generated it

			Dr = {}
			P = {}
			D = []
			# Fill the dicts with default values
			for node in nodes.keys():
				t = [32768,node] # Vertices are unreachable
				D.append(t)
				Dr[node] = t

			D[start][0] = 0 # The start vertex needs no move
			
			D.sort()

			unseen_nodes = set(nodes.keys()) # All nodes are unseen

			count = len(unseen_nodes)
			i=0
			p=-1
			while unseen_nodes:
				pp = 100*i/count
				if pp != p:
					p = pp;
					print(str(p)+"%")
				i+=1
				# Select the node with the lowest value in D (final distance)
				shortest,node = D.pop(0)
					
				# Remove the selected node from unseen_nodes
				unseen_nodes.remove(node)
				
				if shortest > 32767:
					print("The remaining values are unreachable")
					break

				# For each child (ie: connected vertex) of the current node
				for edge, child_node in nodes[node].items():
					if child_node == node or edge in excludes:
						continue
					Dn = Dr[node]
					Dc = Dr[child_node]
					if Dc[0] > Dn[0] + 1:
						Dc[0] = Dn[0] + 1
						D.sort()
						# To go to child_node, you have to go through node via edge
						P[child_node] = (node,edge)
			f = open(filename,"w+")
			pickle.dump(P,f)
			f.close()
		#now, P contains the transitions/eges along the shortest path from the start node (0) to each other node
		formulas = {}
		for dst,(src,edge) in P.items():
			# Set a clean path (ingredient list)
			formula = []
			err = False

			# We begin from the end
			node = value #we'll need to 
			# While we are not arrived at the beginning
			while src != 0:
				formula.insert(0,edge)
				src,edge = P[src]
			formula.insert(0,edge)
			if not err:
				formulas[dst] = formula

		for value,formula in formulas.items():
			try:
				dedup[revpots[value]].add(formula,value)
			except KeyError:
				pass

potions = {}
for key,forms in dedup.items():
	added_forms = []
	for form_to_add in forms.lists:
		for form_to_compare in forms.lists:
			if form_to_add == form_to_compare:
				continue
			if form_to_add - form_to_compare and not form_to_compare - form_to_add:
				break
		else:
			added_forms.append((forms.values[form_to_add],forms.lists[form_to_add]))
	potions[key] = (alleffects[key],added_forms)

potionkeys=["ID",
"invisibility",
"jump",
"nightVision",
"regeneration",
"fireResistance",
"waterBreathing",
"damageBoost",
"digSpeed",
"heal",
"moveSpeed",
"resistance",
"hunger",
"moveSlowdown",
"weakness",
"digSlowDown",
"blindness",
"confusion",
"harm",
"poison",
"invisibilityD","jumpD","nightVisionD","regenerationD","fireResistanceD","waterBreathingD","damageBoostD","digSpeedD","healD","moveSpeedD","resistanceD","hungerD","moveSlowdownD","weaknessD","digSlowDownD","blindnessD","confusionD","harmD","poisonD","bad"]


fpotion = open("potion.csv","w+")
wpotion = csv.DictWriter(fpotion,potionkeys)
wpotion.writeheader()

fformulas = open("formulas.csv","w+")
wformulas = csv.writer(fformulas)
wformulas.writerow(["value","potion","ingredients"])

valueeffects = (
	"damageBoost",
	"digSpeed",
	"heal",
	"moveSpeed",
	"resistance",
	"harm",
	"poison", 
		)

badeffects = (
	'hunger',        
	'moveSlowdown',  
	'weakness'      ,
	'digSlowDown',   
	'blindness',     
	'confusion',     
	'harm',          
	'poison',        
)
for k,v in potions.items():
	effects,forms = v
	for formula in forms:
		wformulas.writerow([str(formula[0]),str(k),"|".join(formula[1])])

	potion = {}
	for field in potionkeys:
		potion[field] = "-1"
	potion["ID"] = str(k)

	bad = 0

	for effect in effects:
		potion[effect[0]]     = str(effect[2])
		potion[effect[0]+"D"] = str(effect[1])
		if effect[0] in badeffects:
			bad += effect[1] * (1+effect[2])

	potion["bad"] = bad
	wpotion.writerow(potion)
fpotion.close()
fformulas.close()


